import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'database_service.dart';

class AppService {
  static final AppService _instance = AppService._internal();
  factory AppService() => _instance;
  AppService._internal();

  /// مۇلازىمەت ئادرېسى - تور بەت شەكلىدە ساندانغا ئۇلىنىش
  static const String apiUrl = 'http://localhost:8080';

  /// ساندان جەدۋىلىنى تەكشۈرۈش
  Future<bool> createUserInfoTable() async {
    try {
      if (kIsWeb) {
        // تور بەت شەكلىدە ساندانغا ئۇلىنىش
        final response = await http
            .get(Uri.parse('$apiUrl/createUserInfoTable'))
            .timeout(const Duration(seconds: 5));

        if (response.statusCode != 200) {
          throw Exception('ساندان جەدۋىلى تەكشۈرۈش خاتالىقى: ${response.body}');
        }
        return true;
      } else {
        // Windows شەكلىدە ساندانغا ئۇلىنىش
        final dbService = DatabaseService();
        return await dbService.createUserInfoTable();
      }
    } catch (e) {
      debugPrint('ساندانغا ئۇلىنىش خاتالىقى: $e');
      throw Exception('ساندانغا ئۇلىنىش خاتالىقى: $e');
    }
  }

  /// ئىشلەتكۈچى كىرىش تەكشۈرۈشى
  Future<bool> login(String username, String password) async {
    try {
      if (kIsWeb) {
        // تور بەت شەكلىدە ساندانغا ئۇلىنىش
        final response = await http.post(
          Uri.parse('$apiUrl/login'),
          body: jsonEncode({'username': username, 'password': password}),
          headers: {'Content-Type': 'application/json'},
        ).timeout(const Duration(seconds: 5));

        debugPrint('كىرىش جاۋابى: ${response.statusCode} - ${response.body}');

        if (response.statusCode == 200) {
          return true;
        } else if (response.statusCode == 401) {
          return false; // ئىشلەتكۈچى نامى ياكى پارول خاتا
        } else {
          throw Exception('كىرىش خاتالىقى: ${response.body}');
        }
      } else {
        // Windows شەكلىدە ساندانغا ئۇلىنىش
        final dbService = DatabaseService();
        return await dbService.login(username, password);
      }
    } catch (e) {
      debugPrint('كىرىش خاتالىقى: $e');
      throw Exception('كىرىش خاتالىقى: $e');
    }
  }

  /// يېڭى ئىشلەتكۈچى قوشۇش
  Future<bool> addUser(String username, String password,
      [String? email]) async {
    try {
      if (kIsWeb) {
        // تور بەت شەكلىدە ساندانغا ئۇلىنىش
        final response = await http.post(
          Uri.parse('$apiUrl/addUser'),
          body: jsonEncode({
            'username': username,
            'password': password,
            'email': email,
          }),
          headers: {'Content-Type': 'application/json'},
        ).timeout(const Duration(seconds: 5));

        debugPrint(
            'ئىشلەتكۈچى قوشۇش جاۋابى: ${response.statusCode} - ${response.body}');

        if (response.statusCode == 200) {
          return true;
        } else if (response.statusCode == 409) {
          return false; // ئىشلەتكۈچى ئاللىقاچان بار
        } else {
          throw Exception('ئىشلەتكۈچى قوشۇش خاتالىقى: ${response.body}');
        }
      } else {
        // Windows شەكلىدە ساندانغا ئۇلىنىش
        final dbService = DatabaseService();
        return await dbService.addUser(username, password, email);
      }
    } catch (e) {
      debugPrint('ئىشلەتكۈچى قوشۇش خاتالىقى: $e');
      throw Exception('ئىشلەتكۈچى قوشۇش خاتالىقى: $e');
    }
  }

  /// پارول ئەسلەش كودى ئەۋەتىش
  Future<String> sendPasswordResetCode(String usernameOrEmail) async {
    try {
      if (kIsWeb) {
        // تور بەت شەكلىدە ساندانغا ئۇلىنىش
        final response = await http.post(
          Uri.parse('$apiUrl/sendPasswordResetCode'),
          body: jsonEncode({'usernameOrEmail': usernameOrEmail}),
          headers: {'Content-Type': 'application/json'},
        ).timeout(const Duration(seconds: 5));

        debugPrint(
            'پارول ئەسلەش كودى ئەۋەتىش جاۋابى: ${response.statusCode} - ${response.body}');

        if (response.statusCode == 200) {
          final Map<String, dynamic> data = jsonDecode(response.body);
          return data['code'] as String;
        } else if (response.statusCode == 404) {
          throw Exception('بۇ ئىشلەتكۈچى نامى ياكى ئېلخەت تېپىلمىدى');
        } else {
          throw Exception(
              'پارول ئەسلەش كودى ئەۋەتىش خاتالىقى: ${response.body}');
        }
      } else {
        // Windows شەكلىدە ساندانغا ئۇلىنىش
        final dbService = DatabaseService();

        // ئىشلەتكۈچىنى ئىزدەش
        final user = await dbService.findUserByUsernameOrEmail(usernameOrEmail);

        if (user == null) {
          throw Exception('بۇ ئىشلەتكۈچى نامى ياكى ئېلخەت تېپىلمىدى');
        }

        // ئادەتتە بۇ يەردە ئېلخەتكە كود ئەۋەتىش مەشغۇلاتى قىلىنىدۇ
        // لېكىن بۇ سىمۇلياتسىيە ئۈچۈن، مەلۇم كودنى ئىشلىتىمىز
        return '123456';
      }
    } catch (e) {
      debugPrint('پارول ئەسلەش كودى ئەۋەتىش خاتالىقى: $e');
      throw Exception('پارول ئەسلەش كودى ئەۋەتىش خاتالىقى: $e');
    }
  }

  /// پارولنى قايتا بەلگىلەش
  Future<bool> resetPassword(String usernameOrEmail, String newPassword) async {
    try {
      if (kIsWeb) {
        // تور بەت شەكلىدە ساندانغا ئۇلىنىش
        final response = await http.post(
          Uri.parse('$apiUrl/resetPassword'),
          body: jsonEncode({
            'usernameOrEmail': usernameOrEmail,
            'newPassword': newPassword,
          }),
          headers: {'Content-Type': 'application/json'},
        ).timeout(const Duration(seconds: 5));

        debugPrint(
            'پارول قايتا بەلگىلەش جاۋابى: ${response.statusCode} - ${response.body}');

        if (response.statusCode == 200) {
          return true;
        } else if (response.statusCode == 404) {
          throw Exception('بۇ ئىشلەتكۈچى نامى ياكى ئېلخەت تېپىلمىدى');
        } else {
          throw Exception('پارول قايتا بەلگىلەش خاتالىقى: ${response.body}');
        }
      } else {
        // Windows شەكلىدە ساندانغا ئۇلىنىش
        final dbService = DatabaseService();

        // پارولنى يېڭىلاش
        return await dbService.updatePassword(usernameOrEmail, newPassword);
      }
    } catch (e) {
      debugPrint('پارول قايتا بەلگىلەش خاتالىقى: $e');
      throw Exception('پارول قايتا بەلگىلەش خاتالىقى: $e');
    }
  }
}
